# -*- coding: utf-8 -*- 

from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch, mm
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import colors
from uuid import uuid4
from cgi import escape
import os
cwd = os.getcwd()
format=MARKMIN

# image locations
# logo_path      =os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','tutorial','logo_pb.png')
logo_path        =os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','voa','logo.png')
voa_logo_path    =os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','voa','logo.png')

# files locations
tmpfilename      =os.path.join(request.folder,'private',str(uuid4()))
JV_20k_c1_path   =os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','tutorial','20k_c1.txt')
JV_20k_c2_path   =os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','tutorial','20k_c2.txt')
cvs_file_path    =os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','invoice.csv')

# 
output_orientation      =    'letter'     # 'A4
output_units            =    'in'         # 'cm', 

def voa_outline():
    '''
    changed import to work with web2py. Corrected page number reference
    
    http://code.google.com/p/pyfpdf/wiki/Tutorial
    
    Header, footer, page break and image
    
This example makes use of the Header and Footer methods to process page headers and footers. They are called automatically. They already exist in the FPDF class but do nothing, therefore we have to extend the class and override them.

The logo is printed with the Image method by specifying its upper-left corner and its width. The height is calculated automatically to respect the image proportions.

To print the page number, a null value is passed as the cell width. It means that the cell should extend up to the right margin of the page; it is handy to center text. The current page number is returned by the PageNo method; as for the total number of pages, it is obtained by means of the special value {nb} which will be substituted on document closure (provided you first called AliasNbPages). Note the use of the SetY method which allows to set position at an absolute location in the page, starting from the top or the bottom.

Another interesting feature is used here: the automatic page breaking. As soon as a cell would cross a limit in the page (at 2 centimeters from the bottom by default), a break is performed and the font restored. Although the header and footer select their own font (Arial), the body continues with Times. This mechanism of automatic restoration also applies to colors and line width. The limit which triggers page breaks can be set with SetAutoPageBreak. 
    
    '''
#    from pyfpdf import FPDF
    from gluon.contrib.pyfpdf import FPDF
    class PDF(FPDF):
        def header(this):

                # Logo
                this.image(name=voa_logo_path,x=10,y=8,w=33,h=0,type='PNG',link='http://voiceofaccess.org/')
                this.set_font(family='Arial',style='B',size=15)
                # Remove bold
                this.set_font('')
                # Move to the right
#                this.cell(4.5)
                this.cell(w=0,h=1,txt='',border=0,ln=0,align='C',fill=0,link='')
                # Title
#                this.cell(30,10,'Title',1,0,'C')
                this.cell(w=4,h=0,txt='Confirmation of Contribution',border=3,ln=0,align='C',fill=0,link='http://voiceofaccess.org/')
                # Line break
                this.ln(20)

        # Page footer
        def footer(this):
                # Position at 1.5 cm from bottom
                this.set_y(-15)
                # Arial italic 8
                this.set_font('Arial','I',8)
                # Page number

                this.cell(0,10,'Page '+str(this.page_no())+'/{nb}',0,0,'C')
    # Instanciation of inherited class
    pdf=PDF(orientation='P',unit='mm',format='letter')
    pdf.alias_nb_pages()
    pdf.add_page()
    pdf.set_font('Times','',12)
    for i in range(1,41):
        pdf.cell(0,10,'Printing line number '+str(i),0,1)
#    return pdf.output('tuto2.pdf','F')
    response.headers['Content-Type']='application/pdf'
    return pdf.output(dest='S')


def voa_simple_template():
    from gluon.contrib.pyfpdf import Template
    import os.path
    elements = [
        { 'name': 'company_logo', 'type': 'I', 'x1': 20.0, 'y1': 17.0, 'x2': 78.0, 'y2': 30.0, 'font': None, 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': 'logo', 'priority': 2, },
        
        { 'name': 'company_name', 'type': 'T', 'x1': 17.0, 'y1': 32.5, 'x2': 115.0, 'y2': 37.5, 'font': 'Arial', 'size': 12.0, 'bold': 1, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, },
        { 'name': 'box', 'type': 'B', 'x1': 15.0, 'y1': 15.0, 'x2': 185.0, 'y2': 260.0, 'font': 'Arial', 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 0, },
        { 'name': 'box_x', 'type': 'B', 'x1': 95.0, 'y1': 15.0, 'x2': 105.0, 'y2': 25.0, 'font': 'Arial', 'size': 0.0, 'bold': 1, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 2, },
        { 'name': 'line1', 'type': 'L', 'x1': 100.0, 'y1': 25.0, 'x2': 100.0, 'y2': 57.0, 'font': 'Arial', 'size': 0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 3, },
        { 'name': 'barcode', 'type': 'BC', 'x1': 20.0, 'y1': 246.5, 'x2': 140.0, 'y2': 254.0, 'font': 'Interleaved 2of5 NT', 'size': 0.75, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '200000000001000159053338016581200810081', 'priority': 3, },
    ]

    f = Template(format="letter",elements=elements,
                 title="Sample Invoice")
    f.add_page()
    f["company_name"] = "Voice of Access"
    f["company_logo"] = logo_path
#    f.render("./template.pdf"
    response.headers['Content-Type']='application/pdf'
    return f.render('template.pdf', dest='S')    




def index():
    """
    example action using the internationalization operator T and flash
    rendered by views/default/index.html or views/generic.html
    """
    response.flash = T('Welcome to web2py')
    return dict(message=T('Hello World'))
    
def outline():
    '''
    changed import to work with web2py. Corrected page number reference
    
    http://code.google.com/p/pyfpdf/wiki/Tutorial
    
    Header, footer, page break and image
    
This example makes use of the Header and Footer methods to process page headers and footers. They are called automatically. They already exist in the FPDF class but do nothing, therefore we have to extend the class and override them.

The logo is printed with the Image method by specifying its upper-left corner and its width. The height is calculated automatically to respect the image proportions.

To print the page number, a null value is passed as the cell width. It means that the cell should extend up to the right margin of the page; it is handy to center text. The current page number is returned by the PageNo method; as for the total number of pages, it is obtained by means of the special value {nb} which will be substituted on document closure (provided you first called AliasNbPages). Note the use of the SetY method which allows to set position at an absolute location in the page, starting from the top or the bottom.

Another interesting feature is used here: the automatic page breaking. As soon as a cell would cross a limit in the page (at 2 centimeters from the bottom by default), a break is performed and the font restored. Although the header and footer select their own font (Arial), the body continues with Times. This mechanism of automatic restoration also applies to colors and line width. The limit which triggers page breaks can be set with SetAutoPageBreak. 
    
    '''
#    from pyfpdf import FPDF
    from gluon.contrib.pyfpdf import FPDF
    class PDF(FPDF):
        def header(this):

                # Logo
#                this.image(logo_path,10,8,33)
                this.image(logo_path,x=10,y=8,w=0,h=0,type='',link='')
                # Arial bold 15
                this.set_font('Arial','B',15)
                # Move to the right
                this.cell(80)
#                this.cell(w=0,h=1,txt='',border=0,ln=0,align='C',fill=0,link='')
                # Title
#                this.cell(30,10,'Title',1,0,'C')
                this.cell(w=.55,h=10,txt='Confirmation of Contribution',border=0,ln=0,align='C',fill=0,link='http://voiceofaccess.org/')
                # Line break
                this.ln(20)

        # Page footer
        def footer(this):
                # Position at 1.5 cm from bottom
                this.set_y(-15)
                # Arial italic 8
                this.set_font('Arial','I',8)
                # Page number
#               this.cell(0,10,'Page '+str(this.PageNo())+'/{nb}',0,0,'C')
                this.cell(0,10,'Page '+str(this.page_no())+'/{nb}',0,0,'C')
    # Instanciation of inherited class
    pdf=PDF(orientation='L',unit='mm',format='letter')
    pdf.alias_nb_pages()
    pdf.add_page()
    pdf.set_font('Times','',12)
    for i in range(1,41):
        pdf.cell(0,10,'Printing line number '+str(i),0,1)
#    return pdf.output('tuto2.pdf','F')
    response.headers['Content-Type']='application/pdf'
    return pdf.output(dest='S')

def colors_and_breaks():
    '''
    Line breaks and colors
    
    Let's continue with an example which prints justified paragraphs. It also illustrates the use of colors.
    '''
#   from fpdf import FPDF
    from gluon.contrib.pyfpdf import FPDF
    title='20000 Leagues Under the Seas'
    class PDF(FPDF):
        def header(self):
                #Arial bold 15
                self.set_font('Arial','B',15)
                #Calculate width of title and position
                w=self.get_string_width(title)+6
                self.set_x((210-w)/2)
                #Colors of frame, background and text
                self.set_draw_color(0,80,180)
                self.set_fill_color(230,230,0)
                self.set_text_color(220,50,50)
                #Thickness of frame (1 mm)
                self.set_line_width(1)
                #Title
                self.cell(w,9,title,1,1,'C',1)
                #Line break
                self.ln(10)

        def footer(self):
                #Position at 1.5 cm from bottom
                self.set_y(-15)
                #Arial italic 8
                self.set_font('Arial','I',8)
                #Text color in gray
                self.set_text_color(128)
                #Page number
                self.cell(0,10,'Page '+str(self.page_no()),0,0,'C')

        def chapter_title(self,num,label):
                #Arial 12
                self.set_font('Arial','',12)
                #Background color
                self.set_fill_color(200,220,255)
                #Title
                self.cell(0,6,"Chapter %d : %s"%(num,label),0,1,'L',1)
                #Line break
                self.ln(4)

        def chapter_body(self,name):
                #Read text file
                txt=file(name).read()
                #Times 12
                self.set_font('Times','',12)
                #Output justified text
                self.multi_cell(0,5,txt)
                #Line break
                self.ln()
                #Mention in italics
                self.set_font('','I')
                self.cell(0,5,'(end of excerpt)')

        def print_chapter(self,num,title,name):
                self.add_page()
                self.chapter_title(num,title)
                self.chapter_body(name)


    pdf=PDF()
    pdf.set_title(title)
    pdf.set_author('Jules Verne')
    pdf.print_chapter(1,'A RUNAWAY REEF',JV_20k_c1_path)
    pdf.print_chapter(2,'THE PROS AND CONS',JV_20k_c2_path)
#   pdf.output('tuto3.pdf','F')
    response.headers['Content-Type']='application/pdf'
    return pdf.output(dest='S')

    
def simple_template():
    from gluon.contrib.pyfpdf import Template
    import os.path
    elements = [
        { 'name': 'company_logo', 'type': 'I', 'x1': 20.0, 'y1': 17.0, 'x2': 78.0, 'y2': 30.0, 'font': None, 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': 'logo', 'priority': 2, },
        
        { 'name': 'company_name', 'type': 'T', 'x1': 17.0, 'y1': 32.5, 'x2': 115.0, 'y2': 37.5, 'font': 'Arial', 'size': 12.0, 'bold': 1, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, },
        { 'name': 'box', 'type': 'B', 'x1': 15.0, 'y1': 15.0, 'x2': 185.0, 'y2': 260.0, 'font': 'Arial', 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 0, },
        { 'name': 'box_x', 'type': 'B', 'x1': 95.0, 'y1': 15.0, 'x2': 105.0, 'y2': 25.0, 'font': 'Arial', 'size': 0.0, 'bold': 1, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 2, },
        { 'name': 'line1', 'type': 'L', 'x1': 100.0, 'y1': 25.0, 'x2': 100.0, 'y2': 57.0, 'font': 'Arial', 'size': 0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 3, },
        { 'name': 'barcode', 'type': 'BC', 'x1': 20.0, 'y1': 246.5, 'x2': 140.0, 'y2': 254.0, 'font': 'Interleaved 2of5 NT', 'size': 0.75, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '200000000001000159053338016581200810081', 'priority': 3, },
    ]

    f = Template(format="letter",elements=elements,
                 title="Sample Invoice")
    f.add_page()
    f["company_name"] = "Voice of Access"
    f["company_logo"] = logo_path
#    f.render("./template.pdf"
    response.headers['Content-Type']='application/pdf'
    return f.render('template.pdf', dest='S')    


def get_me_a_pdf():
    '''
        tmpfilename=os.path.join(request.folder,'private',str(uuid4()))
    '''
    title = "This The Doc Title"
    heading = "First Paragraph"
    text = 'bla '* 10000

    styles = getSampleStyleSheet()
    doc = SimpleDocTemplate(tmpfilename)
    story = []
    story.append(Paragraph(escape(title),styles["Title"]))
    story.append(Paragraph(escape(heading),styles["Heading2"]))
    story.append(Paragraph(escape(text),styles["Normal"]))
    story.append(Spacer(1,2*inch))
    doc.build(story)
    data = open(tmpfilename,"rb").read()
    os.unlink(tmpfilename)
    response.headers['Content-Type']='application/pdf'
    return data

from gluon.contrib.pyfpdf import FPDF
import os

def get_me_a_pyfpdf():
    title = "This The Doc Title"
    heading = "First Paragraph"
    text = 'bla '* 1000

    pdf=FPDF()
    pdf.add_page()
    pdf.set_font('Times','B',15)
    pdf.cell(w=210,h=9,txt=title,border=0,ln=1,align='C',fill=0)
    pdf.set_font('Times','B',15)
    pdf.cell(w=0,h=6,txt=heading,border=0,ln=1,align='L',fill=0)
    pdf.set_font('Times','',12)
    pdf.multi_cell(w=0,h=5,txt=text)
    response.headers['Content-Type']='application/pdf'
    return pdf.output(dest='S')

def report():
    response.title = "web2py sample report"
    
    # include a google chart!
    url = "http://chart.apis.google.com/chart?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World&.png"
    chart = IMG(_src=url, _width="250",_height="100")

    # create a small table with some data:
    rows = [THEAD(TR(TH("Key",_width="70%"), TH("Value",_width="30%"))),
            TBODY(TR(TD("Hello"),TD("60")), 
                  TR(TD("World"),TD("40")))]
    table = TABLE(*rows, _border="0", _align="center", _width="50%")

    if request.extension=="pdf":
        from gluon.contrib.pyfpdf import FPDF, HTMLMixin

        # create a custom class with the required functionalities 
        class MyFPDF(FPDF, HTMLMixin):
            def header(self): 
                "hook to draw custom page header"
                self.image(logo_path,10,8,33)
                self.set_font('Arial','B',15)
                self.cell(65) # padding
                self.cell(60,10,response.title,1,0,'C')
                self.ln(20)
                
            def footer(self):
                "hook to draw custom page header (printing page numbers)"
                self.set_y(-15)
                self.set_font('Arial','I',8)
                txt = 'Page %s of %s' % (self.page_no(), self.alias_nb_pages())
                self.cell(0,10,txt,0,0,'C')
                    
        pdf=MyFPDF()
        # create a page and serialize/render HTML objects
        pdf.add_page()
        pdf.write_html(str(XML(table, sanitize=False)))
        pdf.write_html(str(XML(CENTER(chart), sanitize=False)))
        # prepare PDF to download:
        response.headers['Content-Type']='application/pdf'
        return pdf.output(dest='S')
    else:
        # normal html view:
        return dict(chart=chart, table=table)

def listing():
    response.title = "web2py sample listing"
    
    # define header and footers:
    head = THEAD(TR(TH("Header 1",_width="50%"), 
                    TH("Header 2",_width="30%"),
                    TH("Header 3",_width="20%"), 
                    _bgcolor="#A0A0A0"))
    foot = TFOOT(TR(TH("Footer 1",_width="50%"), 
                    TH("Footer 2",_width="30%"),
                    TH("Footer 3",_width="20%"),
                    _bgcolor="#E0E0E0"))
    
    # create several rows:
    rows = []
    for i in range(1000):
        col = i % 2 and "#F0F0F0" or "#FFFFFF"
        rows.append(TR(TD("Row %s" %i),
                       TD("something", _align="center"),
                       TD("%s" % i, _align="right"),
                       _bgcolor=col)) 

    # make the table object
    body = TBODY(*rows)
    table = TABLE(*[head,foot, body], 
                  _border="1", _align="center", _width="100%")

    if request.extension=="pdf":
        from gluon.contrib.pyfpdf import FPDF, HTMLMixin

        # define our FPDF class (move to modules if it is reused  frequently)
        class MyFPDF(FPDF, HTMLMixin):
            def header(self):
                self.set_font('Arial','B',15)
                self.cell(0,10, response.title ,1,0,'C')
                self.ln(20)
                
            def footer(self):
                self.set_y(-15)
                self.set_font('Arial','I',8)
                txt = 'Page %s of %s' % (self.page_no(), self.alias_nb_pages())
                self.cell(0,10,txt,0,0,'C')
                    
        pdf=MyFPDF()
        # first page:
        pdf.add_page()
        pdf.write_html(str(XML(table, sanitize=False)))
        response.headers['Content-Type']='application/pdf'
        return pdf.output(dest='S')
    else:
        # normal html view:
        return dict(table=table)
        

def import_csv():
    from gluon.contrib.pyfpdf import Template
    f = Template()
#    f.parse_csv(infile="/home/reingart/web2py/gluon/contrib/pyfpdf/invoice.csv", delimiter=";", decimal_sep=",")
    f.parse_csv(infile=cvs_file_path, delimiter=";", decimal_sep=",")
#    for v in f.fields.elements():
    for v in f.fields.elements():
        v['align']=  {'I':'L','D':'R','C':'C','':''}.get(v['align'], 'L')
        v['pdf_template_id'] = 1
        db.pdf_element.insert(**v)


def voa_invoice():
    from gluon.contrib.pyfpdf import Template
    import os.path
    
    # generate sample contributors confirmation form

    import random
    from decimal import Decimal

    # read elements from db 
    
    elements = db(db.pdf_element.pdf_template_id==1).select(orderby=db.pdf_element.priority)

    f = Template(format="letter",
             elements = elements,
             title="VOA Contribution Confirmation", author="Voice of Access",
             subject="Sample Contributors", keywords="Electronic Confirmation of Contribution")

    detail = "Here is our detail." * 5
    items = []
    for i in range(1, 30):
        ds = "Sample product %s" % i
        qty = random.randint(1,10)
        price = round(random.random()*100,3)
        code = "%s%s%02d" % (chr(random.randint(65,90)), chr(random.randint(65,90)),i)
        items.append(dict(code=code, unit='u',
                          qty=qty, price=price, 
                          amount=qty*price,
                          ds="%s: %s" % (i,ds)))

    # divide and count lines
    lines = 0
    li_items = []
    for it in items:
        qty = it['qty']
        code = it['code']
        unit = it['unit']
        for ds in f.split_multicell(it['ds'], 'item_description01'):
            # add item description line (without price nor amount)
            li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None))
            # clean qty and code (show only at first)
            unit = qty = code = None
        # set last item line price and amount
        li_items[-1].update(amount = it['amount'],
                            price = it['price'])

    obs="\n<U>Detail:</U>\n\n" + detail
    for ds in f.split_multicell(obs, 'item_description01'):
        li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None))

    # calculate pages:
    lines = len(li_items)
    max_lines_per_page = 24
    pages = lines / (max_lines_per_page - 1)
    if lines % (max_lines_per_page - 1): pages = pages + 1

    # completo campos y hojas
    for page in range(1, pages+1):
        f.add_page()
        f['page'] = 'Page %s of %s' % (page, pages)
        if pages>1 and page<pages:
            s = 'Continues on page %s' % (page+1)
        else:
            s = ''
        f['item_description%02d' % (max_lines_per_page+1)] = s

        f["company_name"] = "Voice of Access"
        f["company_logo"] = logo_path
        f["company_header1"] = "Montreal 2011"
        f["company_header2"] = "Creating and promoting fair access to resources for Montrealers"
        f["company_footer1"] = "http://www.voiceofaccess.org"
        f["company_footer2"] = "contact@voiceofaccess.org"
        f['number'] = '2011-04171234'
        f['issue_date'] = '2011-04-17'
        f['due_date'] = '2099-09-10'
        f['customer_name'] = "Sample Client"
        f['customer_address'] = "12345 Anystreet, Montreal"
       
        # print line item...
        li = 0 
        k = 0
        total = Decimal("0.00")
        for it in li_items:
            k = k + 1
            if k > page * (max_lines_per_page - 1):
                break
            if it['amount']:
                total += Decimal("%.6f" % it['amount'])
            if k > (page - 1) * (max_lines_per_page - 1):
                li += 1
                if it['qty'] is not None:
                    f['item_quantity%02d' % li] = it['qty']
                if it['code'] is not None:
                    f['item_code%02d' % li] = it['code']
                if it['unit'] is not None:
                    f['item_unit%02d' % li] = it['unit']
                f['item_description%02d' % li] = it['ds']
                if it['price'] is not None:
                    f['item_price%02d' % li] = "%0.3f" % it['price']
                if it['amount'] is not None:
                    f['item_amount%02d' % li] = "%0.2f" % it['amount']

        if pages == page:
            f['net'] = "%0.2f" % (total/Decimal("1.21"))
            f['vat'] = "%0.2f" % (total*(1-1/Decimal("1.21")))
            f['total_label'] = 'Total:'
        else:
            f['total_label'] = 'SubTotal:'
        f['total'] = "%0.2f" % total

    response.headers['Content-Type']='application/pdf'
    return f.render('invoice.pdf', dest='S')



def invoice():
    '''
    logo_path=os.path.join(request.folder,'static','plugin_uc_pyfpdf','pyfpdf','tutorial','logo_pb.png')
        
    '''
    from gluon.contrib.pyfpdf import Template
    import os.path
    
    # generate sample invoice (according Argentina's regulations)

    import random
    from decimal import Decimal

    # read elements from db 
    
    elements = db(db.pdf_element.pdf_template_id==1).select(orderby=db.pdf_element.priority)

    f = Template(format="Letter",
             elements = elements,
             title="Sample Invoice", author="Sample Company",
             subject="Sample Customer", keywords="Electronic TAX Invoice")
    
    detail = "Lorem ipsum dolor sit amet, consectetur. " * 5
    items = []
    for i in range(1, 30):
        ds = "Sample product %s" % i
        qty = random.randint(1,10)
        price = round(random.random()*100,3)
        code = "%s%s%02d" % (chr(random.randint(65,90)), chr(random.randint(65,90)),i)
        items.append(dict(code=code, unit='u',
                          qty=qty, price=price, 
                          amount=qty*price,
                          ds="%s: %s" % (i,ds)))

    # divide and count lines
    lines = 0
    li_items = []
    for it in items:
        qty = it['qty']
        code = it['code']
        unit = it['unit']
        for ds in f.split_multicell(it['ds'], 'item_description01'):
            # add item description line (without price nor amount)
            li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None))
            # clean qty and code (show only at first)
            unit = qty = code = None
        # set last item line price and amount
        li_items[-1].update(amount = it['amount'],
                            price = it['price'])

    obs="\n<U>Detail:</U>\n\n" + detail
    for ds in f.split_multicell(obs, 'item_description01'):
        li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None))

    # calculate pages:
    lines = len(li_items)
    max_lines_per_page = 24
    pages = lines / (max_lines_per_page - 1)
    if lines % (max_lines_per_page - 1): pages = pages + 1

    # completo campos y hojas
    for page in range(1, pages+1):
        f.add_page()
        f['page'] = 'Page %s of %s' % (page, pages)
        if pages>1 and page<pages:
            s = 'Continues on page %s' % (page+1)
        else:
            s = ''
        f['item_description%02d' % (max_lines_per_page+1)] = s

        f["company_name"] = "Sample Company"
        f["company_logo"] = logo_path
        f["company_header1"] = "Some Address - somewhere -"
        f["company_header2"] = "http://www.example.com"
        f["company_footer1"] = "Tax Code ..."
        f["company_footer2"] = "Tax/VAT ID ..."
        f['number'] = '0001-00001234'
        f['issue_date'] = '2010-09-10'
        f['due_date'] = '2099-09-10'
        f['customer_name'] = "Sample Client"
        f['customer_address'] = "Siempreviva 1234"
       
        # print line item...
        li = 0 
        k = 0
        total = Decimal("0.00")
        for it in li_items:
            k = k + 1
            if k > page * (max_lines_per_page - 1):
                break
            if it['amount']:
                total += Decimal("%.6f" % it['amount'])
            if k > (page - 1) * (max_lines_per_page - 1):
                li += 1
                if it['qty'] is not None:
                    f['item_quantity%02d' % li] = it['qty']
                if it['code'] is not None:
                    f['item_code%02d' % li] = it['code']
                if it['unit'] is not None:
                    f['item_unit%02d' % li] = it['unit']
                f['item_description%02d' % li] = it['ds']
                if it['price'] is not None:
                    f['item_price%02d' % li] = "%0.3f" % it['price']
                if it['amount'] is not None:
                    f['item_amount%02d' % li] = "%0.2f" % it['amount']

        if pages == page:
            f['net'] = "%0.2f" % (total/Decimal("1.21"))
            f['vat'] = "%0.2f" % (total*(1-1/Decimal("1.21")))
            f['total_label'] = 'Total:'
        else:
            f['total_label'] = 'SubTotal:'
        f['total'] = "%0.2f" % total

    response.headers['Content-Type']='application/pdf'
    return f.render('invoice.pdf', dest='S')

def user():
    """
    exposes:
    http://..../[app]/default/user/login 
    http://..../[app]/default/user/logout
    http://..../[app]/default/user/register
    http://..../[app]/default/user/profile
    http://..../[app]/default/user/retrieve_password
    http://..../[app]/default/user/change_password
    use @auth.requires_login()
        @auth.requires_membership('group name')
        @auth.requires_permission('read','table name',record_id)
    to decorate functions that need access control
    """
    return dict(form=auth())


def download():
    """
    allows downloading of uploaded files
    http://..../[app]/default/download/[filename]
    """
    return response.download(request,db)


def call():
    """
    exposes services. for example:
    http://..../[app]/default/call/jsonrpc
    decorate with @services.jsonrpc the functions to expose
    supports xml, json, xmlrpc, jsonrpc, amfrpc, rss, csv
    """
    session.forget()
    return service()


def display_static():
    """
    Displays app_name/plugin_font_midnight/static/
    file_path = os.path.join(cwd,'applications',request.application, 'static', 'plugin_uc_pyfpdf', file_name)
    """
    file_name=request.args(0) or redirect(URL('index'))    
    file_path = os.path.join(cwd,'applications',request.application, 'static', 'plugin_uc_pyfpdf', file_name)
    if os.path.exists(file_path):
        content=open(file_path,'r').read()
        body = MARKMIN(content)
    else:
        body = MARKMIN('file not found')
    return dict(body=body)
